﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace DataCoreTechnologies.Scribe
{
   public partial class ConnectionForm : Form
   {
      //Constructor
      public ConnectionForm(SqlConnectionStringBuilder sb)
      {
         InitializeComponent();
         _initialSqlConnection = sb;
         if (sb == null)
         {
            _currentSqlConnection = new SqlConnectionStringBuilder();
            _currentSqlConnection.IntegratedSecurity = true;
            _currentSqlConnection.ConnectTimeout = 30;
         }
         else
            _currentSqlConnection = _initialSqlConnection;

         InitializeAdvancedPage();
         UpdateConnectionPage();
         UpdateAdvancedPage();
         UpdateConnectionStringPage();

         this.ActiveControl = txtServerName;
      }
      public SqlConnectionStringBuilder ConnectionStringBuilder { get; set; }
      #region Form Events
      private void btnTestConnection_Click(object sender, EventArgs e)
      {
         try
         {
            SqlConnection conn = new SqlConnection(_currentSqlConnection.ConnectionString);
            conn.Open();
            conn.Close();
            MessageBox.Show("Successfully connected");
         }
         catch (Exception)
         {
            MessageBox.Show("Error: Unable to connect");
         }
      }
      private void btnCancel_Click(object sender, EventArgs e)
      {
         ConnectionStringBuilder = null;
         this.DialogResult = DialogResult.Cancel;
         this.Close();
      }
      private void btnOK_Click(object sender, EventArgs e)
      {
         System.Diagnostics.Debug.WriteLine("Clicking OK");
         ConnectionStringBuilder = _currentSqlConnection;
         this.DialogResult = DialogResult.OK;
         this.Close();
      }
      private void txtConnectionString_Leave(object sender, EventArgs e)
      {
         try
         {
            SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder();
            sb.ConnectionString = txtConnectionString.Text;
            sb = null;
            _currentSqlConnection.ConnectionString = txtConnectionString.Text;
            UpdateConnectionPage();
            UpdateAdvancedPage();
         }
         catch (ArgumentException)
         {
            MessageBox.Show("Error: Invalid connection string entered");
            this.ActiveControl = txtConnectionString;
         }
         catch (FormatException)
         {
            MessageBox.Show("Error: Invalid connection string entered");
            this.ActiveControl = txtConnectionString;
         }
      }
      private void btnEditValue_Click(object sender, EventArgs e)
      {
         EditAdvancedValue();
      }
      private void radNTAuthentication_CheckedChanged(object sender, EventArgs e)
      {
         txtUserName.Enabled = false;
         txtPassword.Enabled = false;
         _currentSqlConnection.IntegratedSecurity = true;
      
         UpdateConnectionStringPage();
         UpdateAdvancedPage();
      }
      private void radSqlAuthentication_CheckedChanged(object sender, EventArgs e)
      {
         txtUserName.Enabled = true;
         txtPassword.Enabled = true;
         _currentSqlConnection.IntegratedSecurity = false;
         UpdateConnectionStringPage();
         UpdateAdvancedPage();
      }
      private void txtServerName_Leave(object sender, EventArgs e)
      {
         System.Diagnostics.Debug.WriteLine("Leaving text box");
         _currentSqlConnection.DataSource = txtServerName.Text;
         if (radNTAuthentication.Checked)
            _currentSqlConnection.IntegratedSecurity = true;
         else
            _currentSqlConnection.IntegratedSecurity = false;
         UpdateConnectionStringPage();
         UpdateAdvancedPage();
      }
      private void txtUserName_Leave(object sender, EventArgs e)
      {
         _currentSqlConnection.UserID = txtUserName.Text;
         UpdateConnectionStringPage();
         UpdateAdvancedPage();
      }
      private void txtPassword_Leave(object sender, EventArgs e)
      {
         _currentSqlConnection.Password = txtPassword.Text;
         UpdateConnectionStringPage();
         UpdateAdvancedPage();
      }
      private void lviewAdvancedValues_DoubleClick(object sender, EventArgs e)
      {
         EditAdvancedValue();
      }
      #endregion
      #region Private
      //Methods
      private void InitializeAdvancedPage()
      {
         if (_initialSqlConnection == null)
         {
            AddAdvancedViewItem("Connect Timeout", "60", AllowedValueType.Number);
            AddAdvancedViewItem("Data Source", "", AllowedValueType.Any);
            AddAdvancedViewItem("Use Integrated Security", "True", AllowedValueType.Boolean);
            AddAdvancedViewItem("Network Library", "", AllowedValueType.Any);
            AddAdvancedViewItem("Packet Size", "4096", AllowedValueType.Number);
            AddAdvancedViewItem("Password", "", AllowedValueType.Any);
            AddAdvancedViewItem("Persist Security Info", "False", AllowedValueType.Boolean);
            AddAdvancedViewItem("Use Encryption for Data", "False", AllowedValueType.Boolean);
            AddAdvancedViewItem("User Id", "", AllowedValueType.Any);
            AddAdvancedViewItem("Workstation Id", "", AllowedValueType.Any);
         }
         else
         {
            AddAdvancedViewItem("Connect Timeout", _initialSqlConnection.ConnectTimeout.ToString(), AllowedValueType.Number);
            AddAdvancedViewItem("Data Source", _initialSqlConnection.DataSource, AllowedValueType.Any);
            AddAdvancedViewItem("Use Integrated Security", _initialSqlConnection.IntegratedSecurity.ToString(), AllowedValueType.Boolean);
            AddAdvancedViewItem("Network Library", _initialSqlConnection.NetworkLibrary, AllowedValueType.Any);
            AddAdvancedViewItem("Packet Size", _initialSqlConnection.PacketSize.ToString(), AllowedValueType.Number);
            AddAdvancedViewItem("Password", _initialSqlConnection.Password, AllowedValueType.Any);
            AddAdvancedViewItem("Persist Security Info", _initialSqlConnection.PersistSecurityInfo.ToString(), AllowedValueType.Boolean);
            AddAdvancedViewItem("Use Encryption for Data", _initialSqlConnection.Encrypt.ToString(), AllowedValueType.Boolean);
            AddAdvancedViewItem("User Id", _initialSqlConnection.UserID, AllowedValueType.Any);
            AddAdvancedViewItem("Workstation Id", _initialSqlConnection.WorkstationID, AllowedValueType.Any);
         }
      }
      private void AddAdvancedViewItem(string name, string value, AllowedValueType type)
      {
         var item = new ListViewItem(new string[] { name, value });
         item.Tag = type;
         lviewAdvancedValues.Items.Add(item);
      }
      private ListViewItem GetListViewItem(string name)
      {
         foreach (ListViewItem item in lviewAdvancedValues.Items)
            if (item.SubItems[0].Text == name) return item;

         return null;
      }
      private void UpdateAdvancedViewItem(string name, string value)
      {
         var item = GetListViewItem(name);
         if (item != null) item.SubItems[1].Text = value;
      }
      private void UpdateConnectionPage()
      {
         txtServerName.Text = _currentSqlConnection.DataSource;
         txtUserName.Text = _currentSqlConnection.UserID;
         txtPassword.Text = _currentSqlConnection.Password;
         if (_currentSqlConnection.IntegratedSecurity)
         {
            radNTAuthentication.Checked = true;
            radSqlAuthentication.Checked = false;
            txtUserName.Enabled = false;
            txtPassword.Enabled = false;
         }
         else
         {
            radNTAuthentication.Checked = false;
            radSqlAuthentication.Checked = true;
            txtUserName.Enabled = true;
            txtPassword.Enabled = true;
         }

      }
      private void UpdateAdvancedPage()
      {
         UpdateAdvancedViewItem("Connect Timeout", _currentSqlConnection.ConnectTimeout.ToString());
         UpdateAdvancedViewItem("Data Source", _currentSqlConnection.DataSource);
         UpdateAdvancedViewItem("Use Integrated Security", _currentSqlConnection.IntegratedSecurity.ToString());
         UpdateAdvancedViewItem("Network Library", _currentSqlConnection.NetworkLibrary);
         UpdateAdvancedViewItem("Packet Size", _currentSqlConnection.PacketSize.ToString());
         UpdateAdvancedViewItem("Password", _currentSqlConnection.Password);
         UpdateAdvancedViewItem("Persist Security Info", _currentSqlConnection.PersistSecurityInfo.ToString());
         UpdateAdvancedViewItem("Use Encryption for Data", _currentSqlConnection.Encrypt.ToString());
         UpdateAdvancedViewItem("User Id", _currentSqlConnection.UserID);
         UpdateAdvancedViewItem("Workstation Id", _currentSqlConnection.WorkstationID);
      }
      private void UpdateConnectionStringPage()
      {
         txtConnectionString.Text = _currentSqlConnection.ConnectionString;
      }
      private void EditAdvancedValue()
      {
         if (lviewAdvancedValues.SelectedItems.Count == 0)
            MessageBox.Show("Please select a item to modify");
         else
         {
            ListViewItem item = lviewAdvancedValues.SelectedItems[0];

            var propValue = new EditPropertyValueForm(item.SubItems[0].Text,
                                                   item.SubItems[1].Text,
                                                   (AllowedValueType)item.Tag);
            if (propValue.ShowDialog() == DialogResult.OK)
            {
               item.SubItems[1].Text = propValue.Value;

               switch (item.SubItems[0].Text)
               {
                  case "Connect Timeout":
                     System.Diagnostics.Debug.WriteLine(propValue.Value);
                     if (propValue.Value != "")
                        _currentSqlConnection.ConnectTimeout = Convert.ToInt32(propValue.Value);
                     break;
                  case "Data Source":
                     _currentSqlConnection.DataSource = propValue.Value;
                     break;
                  case "Use Integrated Security":
                     _currentSqlConnection.IntegratedSecurity = Convert.ToBoolean(propValue.Value);
                     break;
                  case "Network Library":
                     _currentSqlConnection.NetworkLibrary = propValue.Value;
                     break;
                  case "Packet Size":
                     if (propValue.Value != "")
                        _currentSqlConnection.PacketSize = Convert.ToInt32(propValue.Value);
                     break;
                  case "Password":
                     _currentSqlConnection.Password = propValue.Value;
                     break;
                  case "Persist Security Info":
                     _currentSqlConnection.PersistSecurityInfo = Convert.ToBoolean(propValue.Value);
                     break;
                  case "Use Encryption for Data":
                     _currentSqlConnection.Encrypt = Convert.ToBoolean(propValue.Value);
                     break;
                  case "User Id":
                     _currentSqlConnection.UserID = propValue.Value;
                     break;
                  case "Workstation Id":
                     _currentSqlConnection.WorkstationID = propValue.Value;
                     break;
               }

               UpdateConnectionPage();
               UpdateConnectionStringPage();
            }
         }
      }
      //Properties
      private SqlConnectionStringBuilder _initialSqlConnection = new SqlConnectionStringBuilder();
      private SqlConnectionStringBuilder _currentSqlConnection = new SqlConnectionStringBuilder();
      #endregion
   }
}
